////////////////////////////////////////////////////////////////////////////////

#ifndef _PLAYER_H_
#include "player.h"
#endif

////////////////////////////////////////////////////////////////////////////////

#ifndef _MATHFUNCTIONS_H_
#include "mathfunctions.h"
#endif

////////////////////////////////////////////////////////////////////////////////


// Default player physical constants
const PE::Point defaulPlayerPosition(100, 100);
const PE::Vector defaultPlayerVelocity = {0, 0};
const double defaultPlayerMass = 50;
const double defaultPlayerRadius = 10;
const double defaultPlayerResistanceCoeff = 0.5;

// Default player constants
const size_t defaultPlayerHitPoints = 100;

////////////////////////////////////////////////////////////////////////////////


Player::Player( int _ID )
: GameObject(_ID, defaulPlayerPosition, defaultPlayerVelocity, defaultPlayerMass, defaultPlayerRadius, defaultPlayerResistanceCoeff),
  m_HitPoints(defaultPlayerHitPoints),
  m_LastInputTime(0)
{
}


////////////////////////////////////////////////////////////////////////////////


Player::~Player()
{
}


////////////////////////////////////////////////////////////////////////////////


void Player::Collision(const PhysicalObject* _obj)
{
    const GameObject* obj = GetGameObject(_obj);

    if ( obj->IsBullet() )
    {
        const Bullet* bullet = static_cast<const Bullet*>(obj);
        m_HitPoints -= bullet->GetDamage();
    }
}


////////////////////////////////////////////////////////////////////////////////


size_t Player::GetHitPoints() const
{
    return m_HitPoints;
}


////////////////////////////////////////////////////////////////////////////////


void Player::SetHitPoints( size_t _hitPoints )
{
    m_HitPoints = _hitPoints;
}


////////////////////////////////////////////////////////////////////////////////


const Weapon& Player::GetWeapon() const
{
    return m_Weapon;
}


////////////////////////////////////////////////////////////////////////////////


Bullet* Player::PullTheTrigger()
{
    if ( m_ClientInput.IsShootPressed() )
        return m_Weapon.Shoot( GetID(),
                               GetPosition(),
                               GetShootDirection() );
    else
        return NULL;
}


////////////////////////////////////////////////////////////////////////////////


void Player::ProcessInput( size_t _dt )
{
    // Get direction vector
    PE::Vector vec = {0, 0};
    if ( m_ClientInput.IsGoingRight() )
        vec.vx = 1;
    if ( m_ClientInput.IsGoingLeft() )
        vec.vx = -1;

    if ( m_ClientInput.IsGoingDown() )
        vec.vy = 1;
    if ( m_ClientInput.IsGoingUp() )
        vec.vy = -1;

    // Apply impulse to object
    ApplyImpulse(PE::GetDirection(vec), static_cast<double>(_dt) * 0.02);
}


////////////////////////////////////////////////////////////////////////////////


void Player::SetClientInput( const ClientInput& _input, size_t _creationTime )
{
    if (_creationTime > m_LastInputTime)
    {
        // Set user input
        m_ClientInput = _input;

        // Update time border
        m_LastInputTime = _creationTime;
    }
}


////////////////////////////////////////////////////////////////////////////////


void Player::Revive()
{
    // Set default player state
    m_HitPoints = defaultPlayerHitPoints;
}


////////////////////////////////////////////////////////////////////////////////


bool Player::IsPlayer() const
{
    return true;
}


////////////////////////////////////////////////////////////////////////////////


PE::Direction Player::GetShootDirection() const
{
    PE::Point position = GetPosition();
    PE::Point mousePosition = m_ClientInput.GetMousePosition();

    PE::Vector movementVector = {mousePosition.x - position.x, mousePosition.y - position.y};
    return PE::GetDirection( movementVector );
}


////////////////////////////////////////////////////////////////////////////////
